package com.lwlk.util.regex;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

// 正则工具类
public class Regex {

    public static Regexer is(String regex) {
        return new Regexer(Pattern.compile(regex));
    }

    public static Regexer is(Pattern regex) {
        return new Regexer(regex);
    }

    private static class Regexer {

        private Pattern pattern;

        private Regexer(Pattern pattern) { this.pattern = pattern; }

        // 扫描目标文本，返回一个包含匹配内容的流
        public Stream<String> scan(String context) {
            Iterator<String> scanIterator = new Iterator<String>() {
                private Matcher matcher = pattern.matcher(context);
                @Override public boolean hasNext() {
                    return matcher.find();
                }
                @Override public String next() {
                    return matcher.group();
                }
            };
            return StreamSupport.stream(((Iterable<String>)() -> scanIterator).spliterator(), false);
        }

        // 扫描目标文本，返回一个包含匹配内容和其子分组的List的流，其中List[0]是匹配内容,List[1..-1]是匹配分组
        public Stream<List<String>> scanList(String context) {
            Iterator<List<String>> scanIterator = new Iterator<List<String>>() {
                private Matcher matcher = pattern.matcher(context);
                @Override public boolean hasNext() {
                    return matcher.find();
                }
                @Override public List<String> next() {
                    return IntStream.range(0, matcher.groupCount() + 1).mapToObj(matcher::group).collect(Collectors.toList());
                }
            };
            return StreamSupport.stream(((Iterable<List<String>>)() -> scanIterator).spliterator(), false);
        }

        // 使用正则匹配分割字符串 返回分割开来的字符串流
        public Stream<String> split(String context) {
            return pattern.splitAsStream(context);
        }
    }

    public static void main(String[] args) {

        Regex.is("\\d+").scan("as321d 32as132d1as32 1d3as1 32a1s 1da2s13d 2as1 21 asd2a3s ").collect(Collectors.joining(" "));

        Regex.is("(\\d)(\\d)\\d?").scanList("12as df1 sdf123 12 123 1").map((e) -> String.join(", ", e)).collect(Collectors.joining("\n"));
    }
}
